﻿/**
@author 迷途小羔羊
2012.11.18
*/
module GYLite
{
					
						/**羔羊组件的基础文本组件*/
	export class GYText extends GYTextBase
	{	
		/**-1 字号自适应, 由于白鹭底层设置宽度设置为0则不计算文本尺寸直接返回0，所以此处若设置为0（宽度等于padding + textWidth,textWidth为计算前为0）会导致文本底层返回一直为0，所以为保证底层对文本进行宽度计算，此处应该大于0*/
		public static defualtPadding:number=1;
		// public static indentString:string = " ";
		// public static indent10String:string = "          ";
		// public static indent100String:string = "                                                                                                    ";
		// public static indentSize:number = 0.8876953125;
		protected _autoHeight:boolean;//自适应高度
		protected _autoWidth:boolean;//自适应高度		
		/**上下边距和,当为-1时使用GYText.defualtPadding*/
		protected _padding:number;		
		// protected _indentStr:string;
		protected _invalidFormat:boolean;		
		protected _minWidth:number;
		protected _minHeight:number;
		protected _maxWidth:number;
		protected _maxHeight:number;
		/**是否使用文本测量的失效机制*/
		public useInvalidText:boolean;
		public clipGroup:GYGroup;
		/**是否不参与布局计算*/public offLayout:boolean;		
		
		public constructor(mul:boolean=false)
		{
			super();
			var s = this;				
			s.multiline=mul;
			s.wordWrap=mul;			
		}		
		
		protected initComponent():void
		{var s = this;			
			super.initComponent();
			
			s._minWidth = s._minHeight = NaN;
			s._maxWidth = s._maxHeight = NaN;
			s.textNode.display = this;
			s._batchDrawParam = TextTexture.batchParam;
			// s._indentStr = "";
			s._autoHeight=false;
			s._autoWidth=false;
			s.$textFormat=null;						
			s._htmlStr=null;
			s._invalidFormat=false;			
			s.useInvalidText=true;
			s._padding = -1;			
			s._lineWidthArr = new Array<number>();
			s._lineHeightArr = new Array<number>();
			s.$textFormat = GYSprite.skinTheme?GYSprite.skinTheme.GetTextTextFormat():GYTextBase.defaultFormat;
			s._textStr = "";					
			// if(GYText.defualtFont)
			// {
			// 	s.embedFonts = true;
			// 	s._textFormat.font = GYText.defualtFont;
			// }
			// else 
			if(GYTextBase.defualtSysFont)
				s.font = GYTextBase.defualtSysFont;	
			s.$textFormat.setFormat(s);
			// s.validFormat();
			s.width = NaN;
			s.height = NaN;
			// s.defaultTextFormat=s._textFormat;
			s.addEventListener(egret.Event.CHANGE, s.textChange,s);				
		}				
		protected textChange(e:egret.Event):void
		{var s = this;
			s.validFormat();
		}
		/**刷新文字格式,调用此函数将立即刷新文本格式，否则将在渲染前刷新，建议需要测量时请先调用此函数刷新文本*/
		public validFormat():void
		{var s = this;							
			if(s._autoWidth)
				super.set_width(s.widthCheck(s.textWidth + s.padding));				
			if(s._autoHeight)
				super.set_height(s.heightCheck(s.textHeight + s.padding));				
		}
		
		public updateView():void
		{var s = this;
			if(s._invalidFormat)
			{
				s.validFormat();
				s._invalidFormat = false;
			}
			if(s._invalidBatch)
			{
				s.validBatch();
				s._invalidBatch = false;				
			}
			super.updateView();			
		}
		
		public set bold(b:any)
		{var s = this;
			s.$textFormat.bold=b;
			s.$setBold(b);			
			s.invalidFormat();
		}
		public get bold():any
		{var s = this;
			return s.$textFormat.bold;
		}
		public set size(val:any)
		{var s = this;
			s.$textFormat.size=val;
			s.$setSize(val);			
			s.invalidFormat();
		}
		public get size():any
		{var s = this;
			return s.$textFormat.size;
		}
		public set color(val:any)
		{var s = this;
			s.$textFormat.color=val;			
			s.textColor = val;
			s.$renderDirty = true;
			// s.invalidFormat();
		}
		public get color():any
		{var s = this;
			return s.$textFormat.color;
		}
		public set letterSpacing(val:any)
		{var s = this;
			s.$textFormat.letterSpacing = val;				
			s.invalidFormat();
		}
		public get letterSpacing():any
		{var s = this;
			return s.$textFormat.letterSpacing;
		}
		public set indent(val:any)
		{var s = this;
			if(val == s.$textFormat.indent)return;			
			s.$textFormat.indent = val;
			if(s._htmlStr!=null)
				s.htmlText = s._htmlStr;
			else
				s.text = s._textStr;
		}
		public get indent():any
		{var s = this;
			return s.$textFormat.indent;
		}		
		public set italic(val:any)
		{var s = this;
			s.$textFormat.italic = val;		
			s.$setItalic(val);			
			s.invalidFormat();
		}
		public get italic():any
		{var s = this;
			return s.$textFormat.italic;
		}
		public set font(val:any)
		{var s = this;
			s.$textFormat.font=val;	
			s.$setFontFamily(val);			
			s.invalidFormat();
		}
		public get font():any
		{var s = this;
			return s.$textFormat.font;
		}
		public set leading(val:any)
		{var s = this;
			s.$textFormat.leading=val;
			s.$setLineSpacing(val);
			s.invalidFormat();
		}
		public get leading():any
		{var s = this;
			return s.$textFormat.leading;
		}
		public set align(val:any)
		{var s = this;
			s.$textFormat.align=val;			
			s.textAlign = val;
			s.invalidFormat();
		}
		public get align():any
		{
			return this.$textFormat.align;
		}
		public get contentWidth():number
		{let s = this;
			return s.textWidth + s.padding;
		}
		public get contentHeight():number
		{let s = this;
			return s.textHeight + s.padding;			
		}
		public set autoHeight(val:boolean)
		{var s = this;
//			multiline=true;
			s._autoHeight=val;
			if(val)
				s.set_height(s.heightCheck(s.textHeight + s.padding));				
		}
		public get autoHeight():boolean
		{var s = this;
			return s._autoHeight;
		}
		public set autoWidth(val:boolean)
		{var s = this;
			s._autoWidth=val;
			s.$setWordWrap(false);
			if(val)
				super.set_width(s.widthCheck(s.textHeight + s.padding));				
		}
		public get autoWidth():boolean
		{var s = this;
			return s._autoWidth;
		}
		/**是否描边*/
		public set glow(val:boolean)
		{var s = this;
			if(val)
				s.filters=FilterUtil.blackGlowArr;
			else
				s.filters=null;				
		}
		public set text(str:string)
		{var s = this;					
			s.setText(str);
		}
		public setText(val:string):void
		{
			let s = this;			
			super.$setText(val);
			s._htmlStr = null;
			s._textStr = val;
			if(!s.useInvalidText)
			{				
				s.$renderDirty = true;
				return;
			}
			if(s._autoWidth)
				super.set_width(s.widthCheck(s.textWidth + s.padding));				
			if(s._autoHeight)
				super.set_height(s.heightCheck(s.textHeight + s.padding));				
		}
		public get text():string
		{var s = this;
			if(s._htmlStr != null)
				s._textStr = s._htmlStr.replace(GYText._tagReg, "");
			return s._textStr;		
		}
		public set htmlText(str:string)
		{var s = this;			
			s.setHTML(str);
		}
		protected setHTML(val:string):void
		{
			let s= this;
			s._htmlStr = val;
			s._textStr = null;
			val = (s.$textFormat.underline?"<u>" + val + "</u>":val);			
			s.textFlow = GYTextBase.textParser.parser(val);//s._indentStr
			if(s._autoWidth)
				super.set_width(s.widthCheck(s.textWidth + s.padding));				
			if(s._autoHeight)
				super.set_height(s.heightCheck(s.textHeight + s.padding));				
		}
		public get htmlText():string
		{
			return this._htmlStr;		
		}
		public widthCheck(temp:number):number
		{let s = this;	
			if(s._minWidth == s._minWidth)
			{
				if(temp < s._minWidth)
					temp = s._minWidth;
			}
			if(s._maxWidth == s._maxWidth)
			{
				if(temp > s._maxWidth)
					temp = s._maxWidth;
			}
			return temp;
		}
		public heightCheck(temp:number):number
		{let s = this;			
			if(s._minHeight == s._minHeight)
			{
				if(temp < s._minHeight)
					temp = s._minHeight;
			}
			if(s._maxHeight == s._maxHeight)
			{
				if(temp > s._maxHeight)
					temp = s._maxHeight;
			}
			return temp;
		}		
		public set width(val:number)
		{
			let s = this;
			if(val != val)
			{
				s.autoWidth=true;
				return;
			}
			s._autoWidth=false;
			if(s.multiline)
			{
				s.$setWordWrap(true);			
				if(s._autoHeight)
					super.set_height(s.heightCheck(s.textHeight + s.padding));					
			}				
			super.set_width(val);			
		}
		public get width():number
		{
			return super.get_width();
		}
		public set height(val:number)
		{
			let s = this;
			if(val != val)
			{
				s.autoHeight=true;
				return;
			}
			
			s._autoHeight=false;		
			super.set_height(val);	
		}
		public get height():number
		{
			return super.get_height();
		}
		
		public get padding():number
		{var s = this;
			if(s._padding == -1)
			{
				if(GYText.defualtPadding == -1)
					return ((<any>s.$textFormat.size)/2.5 >> 0);
				return GYText.defualtPadding;
			}
			return s._padding;
		}
		public set padding(val:number)
		{var s = this;
			s._padding = val;
		}
		
		public set textFormat(val:TextFormat)
		{var s = this;			
			val.setFormat(s);		
			s.invalidFormat();
		}
		
		public get textFormat():TextFormat
		{var s = this;
			return s.$textFormat;
		}
		/**格式刷新*/
		public invalidFormat():void
		{var s = this;
			if(!s.useInvalidText)
				return;
			if(s._invalidFormat)
				return;
			s._invalidFormat = true;
			s._invalidBatch = true;
			s.displayChg();
		}
		public stageTextShow():void
		{
			var s = this;
			if(s.hasEventListener(GYViewEvent.STATIC_TEXT_SHOW))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.STATIC_TEXT_SHOW));
		}
		public stageTextHide():void
		{
			var s = this;
			if(s.hasEventListener(GYViewEvent.STATIC_TEXT_HIDE))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.STATIC_TEXT_HIDE));
		}		

		public get minWidth():number
		{let s = this;
			return s._minWidth;
		}

		public set minWidth(value:number)
		{let s = this;
			if(s._minWidth == value)return;
			s._minWidth = value;
			s.invalidFormat();
		}

		public get minHeight():number
		{let s = this;
			return s._minHeight;
		}

		public set minHeight(value:number)
		{let s = this;
			if(s._minHeight == value)return;
			s._minHeight = value;
			s.invalidFormat();
		}

		public get maxWidth():number
		{let s = this;
			return s._maxWidth;
		}

		public set maxWidth(value:number)
		{let s = this;
			if(s._maxWidth == value)return;
			s._maxWidth = value;
			s.invalidFormat();
		}

		public get maxHeight():number
		{let s = this;
			return s._maxHeight;
		}

		public set maxHeight(value:number)
		{let s = this;
			if(s._maxWidth == value)return;
			s._maxHeight = value;
			s.invalidFormat();
		}
		/**替换指定索引上的文本(仅替换文本，不包括下划线)*/
		public replaceTextAt(index:number, text:string, measure:boolean, format:any=null):void
		{
			let s= this;
			let tex:TextTexture,oldTex:TextTexture;
			let batchInfo:BatchInfo;
			let arr:any;
			let batch:boolean;
			let i:number,j:number,n:number,m:number,len:number,len2:number;
			let batchInfos:BatchInfo[];			
			batch = s.isBatch();
			arr = s.$renderNode.drawData;
			if(text == "")
				return;				
			len = arr.length;
			m = n = 0;
			for(i=0;i<len;i+=4)
			{
				if(batch)
				{
					batchInfos = arr[i+3];
					len2 = batchInfos.length;
					for(j=0;j<len2;++j,++n)
					{
						if(n == index)
						{
							tex = TextTexture.getTextTexture(text.charAt(m),s,format);
							batchInfo = AtlasRender.getInstance().addBatch(tex,s);
							if(batchInfo)					
							{
								batchInfo.measureAndDraw();		
								oldTex = <TextTexture>batchInfos[j].$sourceTexture;
								oldTex.$batchManager.removeDisplayBatch(s);
								delete s._charStylesMap[oldTex.hash];
								s._charStylesMap[tex.hash] = tex;
								batchInfos[j] = batchInfo;									
							}							
							++m;
							if(m >= text.length)
								return;
						}					
					}	
				}
				else
				{
					let str:string;					
					str = arr[i];		
					len2 = str.length;
					for(j=0;j<len2;++j,++n)
					{
						if(n == index)
						{		
							arr[i] = str.substring(0,index) + text + str.substring(index + text.length);
							s.$renderDirty = true;
							return;
						}
					}					
				}
				
			}
			if(measure)
				s.$getLinesArr();
		}
	}
}